﻿using Bigway.Common.Logging;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace Bigway.Common.Jobs;

public abstract class BaseBackgroundJob<T>(IServiceScopeFactory serviceScopeFactory,
    string systemId) : IBackgroundJob
{
    private readonly ManualResetEventSlim _manualResetEventSlim = new ManualResetEventSlim(true);

    public async Task ExecuteAsync()
    {
        _manualResetEventSlim.Reset();
        using var scope = serviceScopeFactory.CreateScope();
        var logger = scope.ServiceProvider.GetRequiredService<ILogger<T>>();
        IBackgroundJob job = this;
        var jobId = job.JobId;
        logger.LogInformation("Begin executing the job {JobId}", jobId);
        try
        {
            await DoJob(scope.ServiceProvider, logger);
            logger.LogInformation("The job {JobId} ran successfully", jobId);
        }
        catch (Exception ex)
        {
            logger.LogError(AppLogEvents.BackgroundJob,
                ex,
                "Fatal error happened during execution of the job {JobId}",
                jobId);
        }

        _manualResetEventSlim.Set();
    }

    protected abstract Task DoJob(IServiceProvider serviceProvider, ILogger<T> logger);

    public string SystemId => systemId;
    public string JobName => typeof(T).Name;
    public bool IsRunning => !_manualResetEventSlim.IsSet;
    public void Wait()
    {
        if (_manualResetEventSlim.IsSet)
            return;
        _manualResetEventSlim.Wait();
    }
}